package inventory.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import inventory.common.CommonConstants;
import inventory.common.ResultData;
import inventory.common.RoleLevelEnum;
import inventory.common.UserStatusEnum;
import inventory.entity.Manager;
import inventory.entity.Repository;
import inventory.entity.Role;
import inventory.entity.User;
import inventory.entity.po.UserPo;
import inventory.service.*;
import inventory.utils.PasswordHelper;
import inventory.utils.UUIDUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author Jwx
 * @create 2019-10-28 21:28
 */
@Api(tags = "用户")
@RestController
@RequestMapping(CommonConstants.USER_PREFIX)
public class UserController {

    @Autowired
    UserService userService;
    @Autowired
    RepositoryService repositoryService;
    @Autowired
    ManagerService managerService;
    @Autowired
    RoleService roleService;
    @Autowired
    ManagerPermissionRecordService managerPermissionRecordService;
    @Autowired
    PermissionRecordService permissionRecordService;

    /**
     * @return
     * @author jwx
     * 前端传入要修改用户
     * 根据id修改用户信息
     */
    @RequiresPermissions("user:operate")
    @ApiOperation(value = "根据userId修改用户信息,前端传入修改", notes = "userId必须穿,password、salt、roleId、pid前端不用传入，其他信息前端可以填入修改")
    @ApiImplicitParam(name = "managerId", value = "管理员id")
    @RequestMapping(value = "/modify", method = RequestMethod.POST)
    public ResultData modify(User user, @RequestParam("managerId") String managerId) {

        //ttxxi  2019-12-11 22:03修改
//        PasswordHelper.encryptPassword(user);
//        String workId = user.getWorkId();
//        int res = userService.modifyById(user, workId, managerId);
//        if (res == -1) {
//            return new ResultData().FAILD().setResultIns("该工号不存在或者管理员无此权限!");
//        } else {
//            return new ResultData().OK();
//        }

        Manager manager = userService.queryManagerByUserId(user.getUserId());
        if (!manager.getManagerId().equals(managerId)){
            return new ResultData().FAILD().setResultIns("该用户非当前管理员所管辖");
        }

        //检查workId是否重复
        User selectById = userService.selectById(user.getUserId());//获取到数据库里面当前user的值
        if (!StringUtils.isEmpty(user.getWorkId())){
            if (!selectById.getWorkId().equals(user.getWorkId())){//说明改了工号
                User checkUser = userService.selectOne(new EntityWrapper<User>().eq("work_id", user.getWorkId()));
                if (checkUser!=null){//说明工号重复
                    return new ResultData().FAILD().setResultIns("工号重复");
                }
            }
        }

        user.setPassword(null);
        user.setSalt(null);
        user.setRoleId(null);
        user.setPid(null);
        userService.updateById(user);
        return new ResultData().OK();

    }


    /**
     * @return
     * @author jwx
     * 前端传入要增加的用户对象,管理员id
     * 新增用户
     */
    @RequiresPermissions("user:operate")
    @ApiOperation(value = "新增用户,userId,signIn,pid,salt后台生成（前端设置为null就行），其他信息前端传入")
    @ApiImplicitParam(name = "managerId", value = "管理员id")
    @RequestMapping(value = "/addUser", method = RequestMethod.POST, params = {"managerId"})
    public ResultData addUser(User user, @RequestParam("managerId") String managerId) {

        //ttxxi修改
        Manager manager = managerService.selectById(managerId);
        if (manager==null){
            return new ResultData().FAILD().setResultIns("管理员id错误");
        }else if (manager.getMaxNum()<=manager.getTmpNum()){
            return new ResultData().FAILD().setResultIns("人员已满");
        }

        user.setSignIn(new Date());
        user.setStatus(UserStatusEnum.ACTIVE.getCode());
        PasswordHelper.encryptPassword(user);
        int addUserRes = userService.addUser(user, managerId);
        if (addUserRes == 1) {
            repositoryService.distributionRepository(user, managerId);

            //添加初始权限
            Role role = roleService.selectById(user.getRoleId());
            List<Integer> list = new ArrayList<>();


            switch (Objects.requireNonNull(RoleLevelEnum.getRoleLevelByCode(role.getState()))) {
                case PERSON://个人，暂时初始时没有权限
                    break;
                case COUNTY://县级
                    list.add(3);//入库材料
                    list.add(4);//出库材料
                    list.add(5);//操作材料
                    list.add(6);//调拨材料
                    break;
                case CITY://市级
                    list.add(3);//入库材料
                    list.add(4);//出库材料
                    list.add(5);//操作材料
                    list.add(6);//调拨材料
                    break;
                default:
                    return new ResultData().FAILD().setResultIns("角色信息出错");
            }

            permissionRecordService.addUserPermissionRecord(user.getUserId(), list);

            //更新对应管理员的人数
            long num = manager.getTmpNum();
            manager.setTmpNum(num+1);
            managerService.updateById(manager);

            return new ResultData().OK().setResultIns("添加用户成功");


        } else if (addUserRes == -1) {
            return new ResultData().FAILD().setResultIns("workId已经存在了");
        } else if (addUserRes == -2) {
            return new ResultData().FAILD().setResultIns("性别出错，只允许输入0和1");
        } else if (addUserRes == -3) {
            return new ResultData().FAILD().setResultIns("roleId非法");
        } else if (addUserRes == -5) {
            return new ResultData().FAILD().setResultIns("用户数目已经达到了上限");
        } else {
            return new ResultData().FAILD().setResultIns("未知错误");
        }

    }

    /**
     * @Description: 传入user对象，只需要workId和username其中一个为非null，查询用户
     * @Param: User
     * @return: list
     * @Author: jwx
     * @Date: 2019/11/23
     */
    @ApiOperation(value = "查询用户信息", notes = "传入user对象，只需要workId和username其中一个为非null,")
    @ApiImplicitParam(name = "managerId", value = "管理员id", required = true)
    @RequestMapping(value = "queryUser", method = RequestMethod.POST)
    public ResultData queryUser(User user, @RequestParam("managerId") String managerId) {
        List<UserPo> userPoList = userService.queryUserPo(user, managerId);
        if (userPoList != null) {
            return new ResultData().OK().setObjs(userPoList);
        } else {
            return new ResultData().FAILD().setResultIns("用户不存在或者管理员无权限");
        }

    }

    /**
     * @return
     * @author jwx
     * <p>
     * 根据id和用户类型删除用户
     */
    @Deprecated
    @RequiresPermissions("user:operate")
    @ApiOperation(value = "根据id删除用户", notes = "传入用户id和管理员id")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户userId", required = true),
            @ApiImplicitParam(name = "managerId", value = "管理员id", required = true)
    })
    @RequestMapping(value = "/deleteUserById", method = RequestMethod.POST, params = {"userId", "managerId"})
    public ResultData deleteUserByIdAndType(@RequestParam("userId") String userId, @RequestParam("managerId") String managerId) {
        Integer id = userService.deleteUserById(userId, managerId);
        if (id == -1) {
            return new ResultData().FAILD().setResultIns("用户不存在或该级别用户只存在一个不允许删除或者管理员没有权限删除改用户");
        } else if (id == -2) {
            return new ResultData().FAILD();
        } else {
            return new ResultData().OK().setObjs(id).setResultIns("删除成功");
        }

    }

    @RequiresPermissions("user:operate")
    @ApiOperation(value = "根据id修改用户状态", notes = "传入用户id和管理员id")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户userId", required = true),
            @ApiImplicitParam(name = "managerId", value = "管理员id", required = true),
            @ApiImplicitParam(name = "status", value = "用户状态  1：正常  0：封停", required = true)
    })
    @RequestMapping(value = "/setUserStatusById", method = RequestMethod.GET, params = {"userId", "managerId","status"})
    public ResultData setUserStatusById(@RequestParam("userId") String userId, @RequestParam("managerId") String managerId,@RequestParam("status") String status) {
        Integer id = userService.changeStatusById(userId, managerId,status);
        if (id == -1) {
            return new ResultData().FAILD().setResultIns("用户不存在或者管理员没有权限修改该用户");
        }
            else{
                return new ResultData().OK().setObjs(id).setResultIns("修改成功");
            }
        }




    /**
     * @Description: 查询数据所有用户
     * @Param: null
     * @return: List<User>
     * @Author: jwx
     * @Date: 2019/11/23
     */
    @ApiOperation(value = "管理员查询所管理的所有用户", notes = "返回该管理员所管理的有用户")
    @ApiImplicitParam(name = "managerId", value = "管理员Id", required = true)
    @PostMapping(value = "/selectAllUser", params = {"managerId"})
    public ResultData selectAllUser(@RequestParam("managerId") String managerId) {
        List<UserPo> list = userService.queryAllUser(managerId);
        return new ResultData().OK().setObjs(list);

    }

    @ApiOperation(value = "根据角色查询对应的用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色id"),
            @ApiImplicitParam(name = "managerId", value = "管理员id", required = true)
    })
    @PostMapping(value = "/selectUsersByRole", params = {"roleId", "managerId"})
    public ResultData selectUsersByRole(@RequestParam("roleId") String roleId, @RequestParam("managerId") String managerId) {
        List<UserPo> userPoList = userService.selectUsersByRole(roleId, managerId);
        if (userPoList != null) {
            return new ResultData().setObjs(userPoList);
        } else {
            return new ResultData().setResultIns("没有权限查询该角色或者该角色没有对应的用户");
        }

    }

    //---------------------------ttxxi  start----------------------------------------

    /**
     * 用户登录
     *
     * @param workId
     * @param password
     * @return
     * @author ttxxi
     */
    @ApiOperation("用户/管理员登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "workId", value = "员工工号", required = true),
            @ApiImplicitParam(name = "password", value = "密码", required = true),
            @ApiImplicitParam(name = "type", value = "登录类型，0：普通用户，1：管理员", required = true)
    })
    @RequestMapping(value = "/login", method = RequestMethod.GET, params = {"workId", "password", "type"})
    public ResultData login(String workId, String password, String type) {

        if (workId != null && !workId.isEmpty() && password != null && !password.isEmpty()) {
            JSONObject res = userService.login(workId, password, type);
            if (res == null) {
                return new ResultData().FAILD().setResultIns("请检查工号、密码、类型是否正确或账号是否过期");
            }
            return new ResultData().OK().setObjs(res);
        } else {
            return new ResultData().FAILD();
        }
    }

    @RequiresPermissions("manager:operate")
    @ApiOperation("添加管理员")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "workId", required = true, value = "工号"),
            @ApiImplicitParam(name = "manager", required = true, value = "管理员名称"),
            @ApiImplicitParam(name = "password", required = true, value = "密码"),
            @ApiImplicitParam(name = "timeLimit", required = true, value = "账号到期时间(格式yyyy-MM-dd)"),
            @ApiImplicitParam(name = "maxNum", required = true, value = "子用户最大数"),
    })
    @RequestMapping(value = "/addManager", method = RequestMethod.POST)
    public ResultData addManager(Manager manager) {
        //判断到期时间是否合法
        if (manager.getTimeLimit().before(new Date())) {
            return new ResultData().FAILD().setResultIns("账号到期时间小于当前时间");
        }
        //判断workId是否重复
        if (managerService.selectOne(new EntityWrapper<Manager>().eq("work_id", manager.getWorkId())) != null) {
            return new ResultData().FAILD().setResultIns("workId重复");
        }
        //先添加管理员
        manager.setManager(manager.getManager() + "管理员");
        manager.setStatus(UserStatusEnum.ACTIVE.getCode());
        if (userService.addManager(manager)) {
            //添加对应的市级角色
            Role role = new Role();
            role.setRoleId(UUIDUtils.getId());
            role.setRole(manager.getManager().substring(0, manager.getManager().length() - 3));
            role.setPid(manager.getManagerId());
            role.setState(RoleLevelEnum.CITY.getCode());
            roleService.insert(role);

            //创建对应的市级仓库
            Repository repository = new Repository();
            repository.setRepositoryId(UUIDUtils.getId());
            repository.setRoleId(role.getRoleId());
            repository.setRepositoryName(role.getRole() + "的仓库");
            repository.setBelongingStatus(RoleLevelEnum.CITY.getCode());
            repository.setUserId(null);
            repositoryService.insert(repository);

            // 添加管理员对应初始权限
            List<Integer> list = new ArrayList<>();
            list.add(1);
            list.add(5);
            list.add(7);
            list.add(8);
            managerPermissionRecordService.addManagerPermissionRecord(manager.getManagerId(), list);

            return new ResultData().OK();
        } else {
            return new ResultData().FAILD();
        }
    }

    @RequiresPermissions("manager:operate")
    @ApiOperation("根据id更新管理员信息（传什么参数更新什么参数）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "managerId", required = true, value = "管理员id")
    })
    @PostMapping("/updateManagerById")
    public ResultData updateManagerById(Manager manager) {

        //检查workId是否重复
        Manager selectById = managerService.selectById(manager.getManagerId());
        if (!StringUtils.isEmpty(manager.getWorkId())){
            if (!selectById.getWorkId().equals(manager.getWorkId())){//说明改了工号
                Manager checkManager = managerService.selectOne(new EntityWrapper<Manager>().eq("work_id", manager.getWorkId()));
                if (checkManager!=null){//说明工号重复
                    return new ResultData().FAILD().setResultIns("工号重复");
                }
            }
        }

        manager.setPassword(null);
        manager.setSalt(null);
        managerService.updateById(manager);
        return new ResultData().OK();
    }

    @Deprecated
    @RequiresPermissions("manager:operate")
    @ApiOperation("根据id删除管理员")
    @ApiImplicitParam(name = "managerId")
    @GetMapping("deleteManagerById")
    public ResultData deleteManager(String managerId) {
        managerService.deleteById(managerId);

        return new ResultData().OK();
    }

    @RequiresPermissions("manager:operate")
    @ApiOperation("根据管理员id设置管理员状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "managerId",required = true,value = "管理员的id"),
            @ApiImplicitParam(name = "status",required = true,value = "状态 1：正常  0：封停"),
    })
    @GetMapping("setManagerStatusById")
    public ResultData setManagerStatusById(String managerId,String status) {

        Manager manager = managerService.selectById(managerId);
        if(manager==null){
            return new ResultData().FAILD().setResultIns("管理员不存在");
        }

        //修改状态
        manager.setStatus(status);
        managerService.updateById(manager);

        return new ResultData().OK();
    }



    @RequiresPermissions("manager:operate")
    @ApiOperation("获取所有的管理员")
    @GetMapping("/selectAllManager")
    public ResultData selectAllManager() {
        List<Manager> managers = managerService.selectList(new EntityWrapper<Manager>().isNotNull("pid"));
        return new ResultData().OK().setObjs(managers);
    }

    @ApiOperation("根据管理员id获取管理员信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "managerId", required = true, value = "管理员id")
    })
    @GetMapping("selectManagerById")
    public ResultData selectManagerById(String managerId) {
        Manager manager = managerService.selectOne(new EntityWrapper<Manager>().eq("manager_id", managerId));
        return new ResultData().OK().setObjs(manager);
    }

    @ApiOperation("根据用户id查询管理员")
    @ApiImplicitParam(name = "userId", required = true, value = "用户id")
    @GetMapping("queryManagerByUserId")
    public ResultData queryManagerByUserId(String userId) {
        Manager manager = userService.queryManagerByUserId(userId);
        return new ResultData().OK().setObjs(manager);
    }

    @ApiOperation("修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", required = true, value = "管理员:0  非管理员：1"),
            @ApiImplicitParam(name = "workId", required = true, value = "工号"),
            @ApiImplicitParam(name = "oldPassword", required = true, value = "旧密码"),
            @ApiImplicitParam(name = "newPassWord", required = true, value = "新密码")
    })
    @PostMapping("changePassword/{type}")
    public ResultData changePassword(@PathVariable("type") String type, String workId, String oldPassword, String newPassWord) {

        String encryptPassword;
        String checkEncryptPassword;

        switch (type) {
            case "0":
                Manager manager = managerService.selectOne(new EntityWrapper<Manager>().eq("work_id", workId));
                ///判断用户是否存在
                if (manager == null) {
                    return new ResultData().FAILD().setResultIns("用户不存在");
                }
                //判断密码是否正确
                encryptPassword = manager.getPassword();
                manager.setPassword(oldPassword);
                checkEncryptPassword = PasswordHelper.getEncryptPassword(manager);
                if (!encryptPassword.equals(checkEncryptPassword)) {
                    return new ResultData().FAILD().setResultIns("旧密码错误");
                }

                //新密码加密
                manager.setPassword(newPassWord);
                PasswordHelper.encryptPassword(manager);
                managerService.updateById(manager);
                return new ResultData().OK();

            case "1":
                User user = userService.selectOne(new EntityWrapper<User>().eq("work_id", workId));
                ///判断用户是否存在
                if (user == null) {
                    return new ResultData().FAILD().setResultIns("用户不存在");
                }
                //判断密码是否正确
                encryptPassword = user.getPassword();
                user.setPassword(oldPassword);
                checkEncryptPassword = PasswordHelper.getEncryptPassword(user);
                if (!encryptPassword.equals(checkEncryptPassword)) {
                    return new ResultData().FAILD().setResultIns("旧密码错误");
                }

                //新密码加密
                user.setPassword(newPassWord);
                PasswordHelper.encryptPassword(user);
                userService.updateById(user);
                return new ResultData().OK();

            default:
                return new ResultData().FAILD().setResultIns("type类型出错");
        }

    }

    @RequiresPermissions("user:operate")
    @ApiOperation("重置用户密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "managerId", required = true, value = "当前管理员Id"),
            @ApiImplicitParam(name = "userId", required = true, value = "被重置密码的用户的id")
    })
    @GetMapping("resetUserPassword")
    public ResultData resetUserPassword(String managerId,String userId){
        Manager manager = userService.queryManagerByUserId(userId);
        if (manager==null){
            return new ResultData().FAILD().setResultIns("非法请求");
        }
        if (!manager.getManagerId().equals(managerId)){
            return new ResultData().FAILD().setResultIns("用户并非为当前管理员管辖");
        }

        User user = new User();
        user.setUserId(userId);
        user.setPassword("123456");//设置重置的密码为123456
        PasswordHelper.encryptPassword(user);

        userService.updateById(user);

        return new ResultData().OK();
    }

    @RequiresPermissions("manager:operate")
    @ApiOperation("重置管理员密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "managerId", required = true, value = "被重置密码的管理员Id"),

    })
    @GetMapping("resetManagerPassword")
    public ResultData resetManagerPassword(String managerId){

        Manager manager = managerService.selectById(managerId);
        if (manager==null){
            return new ResultData().FAILD().setResultIns("管理员id不存在");
        }

        manager.setPassword("123456");//设置重置的密码为123456
        PasswordHelper.encryptPassword(manager);

        managerService.updateById(manager);

        return new ResultData().OK();
    }


    //---------------------------ttxxi  end----------------------------------------

}

